package cn.edu.zju.gis.disasterBE.sever.service;

import cn.edu.zju.gis.disasterBE.sever.dao.imageDownDao;
import cn.edu.zju.gis.disasterBE.sever.entity.imageQuery;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RequestCallback;
import org.springframework.web.client.RestTemplate;

import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.sql.Timestamp;
import java.util.*;

import org.geotools.geojson.geom.GeometryJSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Service
public class ImageDownService {
    private static final int buffer = 2048;
    private static int cnt = 0;


    public static List<imageQuery> selectAll(){
        return imageDownDao.selectAll();
    }

    public static String imageSearch(double lat, double lng, int did, Timestamp beginPosition,Timestamp endPosition, String aoi, String num) throws DocumentException {
        RestTemplate restTemplate = new RestTemplate();
        Logger logger = LoggerFactory.getLogger(ImageDownService.class);
        String ret = null;
        GeometryJSON gjson = new GeometryJSON();
        // be sure to strip whitespace
        //String json = "{\"type\":\"Point\",\"coordinates\":[100.1,0.1]}";
        try{
            Reader reader = new StringReader(aoi);
            Geometry geometry  = gjson.read(reader);
            ret = geometry.toText();
//            GeometryJSON geometryJson = new GeometryJSON(6);
//            StringWriter writer = new StringWriter();
//            geometryJson.write(p, writer);
//            System.out.println(writer.toString());
//            writer.close();
        }catch (Exception e){
            logger.error(e.getMessage(), e);
        }
        //System.out.println(ret);
        if (ret == null || ret.length() == 0){
            ret = lat +"," + lng;
        }
        String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
        logger.trace(DateFormatUtils.format(beginPosition, pattern));//DateFormatUtils.format(beginPosition, pattern);
        String url = "https://scihub.copernicus.eu/dhus/search?start="+num+"&rows=100&q=(footprint:\"Intersects(" + ret + ")\") AND (platformname:Sentinel-2) AND (cloudcoverpercentage: [0 TO 5]) AND (beginposition:[" + DateFormatUtils.format(beginPosition, pattern) +" TO NOW])&orderby=beginposition asc";
        //String url = "https://scihub.copernicus.eu/dhus/search?start="+num+"&rows=100&q=(footprint:\"Intersects(" + ret + ")\") AND (platformname:Sentinel-2) AND (cloudcoverpercentage: [0 TO 5]) AND (beginposition:[" + beginPosition+" TO "+endPosition+"])";
        //String targetPath = "D:\\3s_test";
        System.out.print(url);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic emhhbmdmZW5nOnpoYW5nZmVuZ2RhcWlhbg==");
        headers.add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.164 Safari/537.36");
        HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
        String body = response.getBody();

        //System.out.print(body);
        ArrayList<imageQuery> iqList = ImageDownService.readXML(body, did);
        if (iqList == null) {
            System.out.print("fuck");
        }
        return body;
    }

    public static void imageDownload(String id, String path) throws IOException {
        String url = "https://scihub.copernicus.eu/dhus/odata/v1/Products('" + id + "')/$value";
        System.out.println(url);
        System.out.println(path);
//        URL url = new URL(netAddress);
//        URLConnection conn = url.openConnection();
//        conn.setRequestProperty("authorization","Basic emhhbmdmZW5nOnpoYW5nZmVuZ2RhcWlhbg==");
//        InputStream inputStream = conn.getInputStream();
//        FileOutputStream fileOutputStream = new FileOutputStream("D:\\3s_test\\test");

        RequestCallback requestCallback = request -> {
            request.getHeaders().setAccept(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM, MediaType.ALL));
            request.getHeaders().add("Authorization", "Basic emhhbmdmZW5nOnpoYW5nZmVuZ2RhcWlhbg==");
            request.getHeaders().add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");
        };
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.execute(url, HttpMethod.GET, requestCallback, clientHttpResponse -> {

            //Files.copy(clientHttpResponse.getBody(), Paths.get("D:\\3s_test\\test"));
            InputStream inputStream = clientHttpResponse.getBody();
            FileOutputStream fileOutputStream = new FileOutputStream(path + "/" + id + ".zip");

            int bytesum = 0;
            int byteread;
            byte[] buffer = new byte[1024];
            while ((byteread = inputStream.read(buffer)) != -1) {
                bytesum += byteread;
                if (bytesum % (1024) == 0){
                    System.out.print((bytesum / (1024)) + "KB");
                }
                fileOutputStream.write(buffer, 0, byteread);
            }
            fileOutputStream.close();
            return null;
        });




    }

    public static ArrayList<imageQuery> readXML(String s ,int did) throws DocumentException {

        SAXReader reader = new SAXReader();
        InputStream in = new ByteArrayInputStream(s.getBytes());
        Document doc = reader.read(in);

        ArrayList<imageQuery> iqList = new ArrayList<>();
        imageQuery iQ = new imageQuery();
        Element root = doc.getRootElement();

        Map map = new HashMap();
        map.put("feed", "http://www.w3.org/2005/Atom");

        XPath x = root.createXPath("//feed:" + "entry");
        x.setNamespaceURIs(map);
        List<Node> ns = x.selectNodes(root);
        for (Node entry:ns
             ) {

        }
        cnt = -1;
        for (Iterator<Element> it = root.elementIterator("entry"); it.hasNext(); ) {
            cnt ++;
            System.out.print(cnt);
            Element entry = it.next();
            iQ.id = entry.elementText("id");


            RestTemplate restTemplate = new RestTemplate();

            String url =  "https://scihub.copernicus.eu/dhus/odata/v1/Products('"+iQ.id+"')/";
            HttpHeaders headers = new HttpHeaders();
            headers.add("Authorization", "Basic emhhbmdmZW5nOnpoYW5nZmVuZ2RhcWlhbg==");
            HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
            ResponseEntity<String> response = restTemplate.exchange(url,HttpMethod.GET,entity, String.class);
            String check = response.getBody();
            //System.out.print(check);
            if(check.indexOf("\"Online\":false,") != -1){
                System.out.print("no");
                continue;
            }

            iQ.cloudcoverpercentage = Double.parseDouble(getXmlValue("double", "cloudcoverpercentage", entry));
            iQ.footprint = getXmlValue("str", "footprint", entry);
            iQ.instrumentname = getXmlValue("str", "instrumentname", entry);
            iQ.platformname = getXmlValue("str", "platformname", entry);
            iQ.orbitnumber = Integer.parseInt(getXmlValue("int", "orbitnumber", entry));
            iQ.resolution = 10;
            iQ.title = entry.elementText("title");
            iQ.producttype = getXmlValue("str", "producttype", entry);
            iQ.date = getXmlValue("date", "beginposition", entry);
            iQ.relativeorbitnumber = Integer.parseInt(getXmlValue("int", "relativeorbitnumber", entry));
            iQ.did = did;
            iQ.filename = "default";

            System.out.print(iQ.footprint);

            imageDownDao.write(iQ);
            iqList.add(iQ);
        }
        return iqList;
    }

    public static String getXmlValue(String tag, String attr, Element e) {
        Map map = new HashMap();
        map.put("feed", "http://www.w3.org/2005/Atom");

        XPath x = e.createXPath("//feed:"+ tag + "[@name='" + attr + "']");
        x.setNamespaceURIs(map);

        List<Node> n = x.selectNodes(e);
        return n.get(cnt).getText();
        //return n.getText();
    }

}

